home *** CD-ROM | disk | FTP | other *** search
/ Mission 3 / Mission 3.zip / Mission 3.iso / texte / 7up_pd / numerik.c < prev    next >
C/C++ Source or Header  |  1998-10-29  |  11KB  |  446 lines

  1. /* Numerischen Funktionen (numerisch bald mit Doppel-m ;-)) */
  2. /* Im Resourcefile muβ es statt 'Gleichung lösen', 'Ausdruck auswerten' heiβen */
  3. /*****************************************************************************
  4. *
  5. *                                              7UP
  6. *                                        Modul: NUMERIK.C
  7. *                                     (c) by TheoSoft '91
  8. *
  9. *****************************************************************************/
  10. #include <portab.h> 
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include <math.h>
  16. #include <aes.h>
  17.  
  18. #include "alert.h"
  19. #include "7up.h"
  20. #include "windows.h"
  21. #include "forms.h"
  22.  
  23. #if GEMDOS
  24.  
  25. extern OBJECT *winmenu, *nummenu;
  26. extern char alertstr[];
  27. extern int cut;
  28.  
  29. double interpretiere(char *gleichung, int *fehler);
  30.  
  31. /* jetzt unnötig, weil im Dialog einstellbar
  32. static char dummy[]="MWST";
  33. */
  34. static char  mwst[]="15.00";
  35. static int      nkst=2;              /* 2 Nachkommastellen */
  36. int komma;
  37.  
  38. int isnum(char c)
  39. {
  40.    if(nummenu[NUMNDT].ob_state & SELECTED)         /* Notation: deutsch */
  41.         return(isdigit(c) || (c=='+') || (c=='-') || (c=='.'));
  42.     else
  43.         return(isdigit(c) || (c=='+') || (c=='-') || (c==','));
  44. }
  45.  
  46. static int isfloat(char *num)
  47. {
  48.     register int i,k=strlen(num);
  49.     for(i=0; i<k; i++)
  50.         if(!(isdigit(num[i]) || (num[i]=='-') || 
  51.                                 (num[i]=='+') || 
  52.                                 (num[i]=='.') || 
  53.                                 (num[i]==',') || isspace(num[i])))
  54.             return(FALSE);
  55.     return(TRUE);
  56. }
  57.  
  58. static void dt2ami(char *str)       /* Dezimalkomma in Punkt verwandeln */
  59. {                                         /* und Tausenderseparatoren entfernen */
  60.     register char *cp;
  61.    if(nummenu[NUMNDT].ob_state & SELECTED)         /* Notation: deutsch */
  62.    {
  63.          if(cp=strrchr(str,','))
  64.         {
  65.             *cp='.';
  66.             while((cp-=4)>str)
  67.                 if(*cp=='.')
  68.                     memmove(cp,cp+1,strlen(cp+1)+1);
  69.             return;
  70.         }
  71.     }
  72.     else                                                      /* Notation: englisch */
  73.     {
  74.         if(cp=strrchr(str,'.'))
  75.         {
  76.             while((cp-=4)>str)
  77.                 if(*cp==',')
  78.                     memmove(cp,cp+1,strlen(cp+1)+1);
  79.             return;
  80.         }
  81.     }
  82. }
  83.  
  84. static void ami2dt(char *str)      /* Dezimalpunkt in Komma verwandeln */
  85. {
  86.     register char *cp;
  87.     if(nummenu[NUMNDT].ob_state & SELECTED)
  88.         if(cp=strrchr(str,'.'))
  89.             *cp=',';
  90. }
  91.  
  92. static void tsep(char *str)
  93. {
  94.     register char *cp;
  95.     if(nummenu[NUMTSEP].ob_state & SELECTED)
  96.     {
  97.         if(cp=strrchr(str,','))
  98.         {
  99.             while((cp-=3)>str)
  100.             {
  101.                 memmove(cp+1,cp,strlen(cp)+1);
  102.                 *cp='.';
  103.             }
  104.             return;
  105.         }
  106.         if(cp=strrchr(str,'.'))
  107.         {
  108.             while((cp-=3)>str)
  109.             {
  110.                 memmove(cp+1,cp,strlen(cp)+1);
  111.                 *cp=',';
  112.             }
  113.             return;
  114.         }
  115.     }
  116. }
  117.  
  118. static void nconvert(char *str)
  119. {
  120.     ami2dt(str);                        /* Dezimalpunkt in Komma verwandeln */
  121.     tsep(str);                                    /* Tausendertrennung einfügen */
  122. }
  123.  
  124. static int count(LINESTRUCT *begin, LINESTRUCT *end)
  125. {
  126.     LINESTRUCT *help;
  127.     int count;
  128.  
  129.     for(count=0,help=begin; help!=end->next; help=help->next)
  130.         if(help->begcol<help->used)
  131.         {
  132.             strncpy(alertstr,&help->string[help->begcol],min(help->endcol,help->used)-help->begcol);
  133.             alertstr[min(help->endcol,help->used)-help->begcol]=0;
  134.             if(isfloat(alertstr))
  135.                 count++;
  136.             *alertstr=0;
  137.         }
  138.     return(count);
  139. }
  140.  
  141. static double sum(LINESTRUCT *begin, LINESTRUCT *end)
  142. {
  143.     LINESTRUCT *help;
  144.     double wert,summe;
  145.  
  146.     for(summe=0.0, help=begin; help!=end->next; help=help->next)
  147.     {
  148.         if(help->begcol<help->used)
  149.         {
  150.             strncpy(alertstr,&help->string[help->begcol],min(help->endcol,help->used)-help->begcol);
  151.             alertstr[min(help->endcol,help->used)-help->begcol]=0;
  152.             if(isfloat(alertstr))
  153.             {
  154.                 dt2ami(alertstr);      /* Dezimalkomma in Punkt verwandeln */
  155.                 sscanf(alertstr,"%lf",&wert);
  156.                 summe+=wert;
  157.             }
  158.             *alertstr=0;
  159.         }
  160.     }
  161.     return(summe);
  162. }
  163.  
  164. #define SQR(a) ((a)*(a))
  165.  
  166. static double sdev(LINESTRUCT *begin, LINESTRUCT *end)
  167. {
  168.     LINESTRUCT *help;
  169.     double summe=0,wert=0,x=0,mean=0;
  170.     int n=0;
  171.     if((n=count(begin, end)) == 0 || n == 1)
  172.     {
  173.         return(-1.0);
  174.     }
  175.     mean=sum(begin, end)/(double)(n);
  176.  
  177.     for(summe=0.0, help=begin; help!=end->next; help=help->next)
  178.     {
  179.         if(help->begcol<help->used)
  180.         {
  181.             strncpy(alertstr,&help->string[help->begcol],min(help->endcol,help->used)-help->begcol);
  182.             alertstr[min(help->endcol,help->used)-help->begcol]=0;
  183.             if(isfloat(alertstr))
  184.             {
  185.                 dt2ami(alertstr);      /* Dezimalkomma in Punkt verwandeln */
  186.                 sscanf(alertstr,"%lf",&wert);
  187.                 summe+=SQR((wert-mean));
  188.             }
  189.             *alertstr=0;
  190.         }
  191.     }
  192.     return(sqrt(summe/(n-1)));
  193. }
  194.  
  195. double steuer(LINESTRUCT *begin, LINESTRUCT *end)
  196. {
  197.     return(sum(begin, end)*(atof(mwst)/100));
  198. }
  199. #endif
  200.  
  201. static char *extract(char *beg, int n, char *gleichung)
  202. {
  203.    strncpy(gleichung,beg,min(n,63));
  204.    gleichung[min(n,PATH_MAX)]=0;
  205.    return(gleichung);
  206. }
  207.  
  208. void rechnen(WINDOW * wp, OBJECT *tree, int operation, LINESTRUCT *begin, LINESTRUCT *end)
  209. {
  210. #if MSDOS
  211.     return;
  212. #else
  213.     FILE *fp;
  214.     char filename[PATH_MAX],openmodus[2],fmtstr[9]="%0.2lf\n";
  215.     static int first=TRUE;
  216.     int fehler, ret, kstate, n, wert1;
  217.     double wert2,wert3,wert4,wert5,wert6;
  218.  
  219.     if(begin && end && !cut)
  220.     {
  221.         scrp_read(filename);
  222.         if(!*filename)
  223.         {
  224. #if GEMDOS
  225.             if(create_clip())
  226.                 scrp_read(filename);
  227.             else
  228.             {
  229.                 form_alert(1,Anumerik[0]);
  230.                 return;
  231.             }
  232. #endif
  233.         }
  234.         else
  235.         {
  236.             if(first) /* beim erstenmal Clipbrd löschen */
  237.             {
  238.                 scrp_clear();
  239.                 first=FALSE;
  240.             }
  241.         }
  242.       complete_path(filename); /* evtl. Slash oder Backslash anhängen */
  243. /*      
  244.         if(filename[strlen(filename)-1]!='\\')
  245.             strcat(filename,"\\");
  246. */
  247.         strcat(filename,"SCRAP.TXT");
  248.         graf_mkstate(&ret,&ret,&ret,&kstate);
  249.         if(kstate & (K_LSHIFT|K_RSHIFT))/* bei gedrückter Shifttaste... */
  250.             strcpy(openmodus,"a");                     /* an Datei anhängen,...*/
  251.         else
  252.             strcpy(openmodus,"w");                 /* ...sonst neue Datei         */
  253.  
  254.       if(tree[NUMNORM].ob_state&SELECTED)  /* MWST lesen */
  255.          form_read(tree,NUMMWSTN,mwst);
  256.       if(tree[NUMERM ].ob_state&SELECTED)
  257.          form_read(tree,NUMMWSTE,mwst);
  258.         dt2ami(mwst); /* Dezimalkomma in Punkt wandeln, falls notwendig */
  259.  
  260.         fmtstr[3]=(char)nkst+'0';                 /* Nachkommastellen setzen */
  261.         *alertstr=0;
  262.  
  263.         graf_mouse(BUSY_BEE,NULL);
  264.         if((fp=fopen(filename,openmodus))!=NULL)
  265.         {
  266.             switch(operation)
  267.             {
  268.                 case BLKCNT:
  269.                     fprintf(fp,"%d\n",wert1=count(begin, end));
  270.                     sprintf(alertstr,Anumerik[1],wert1);
  271.                     break;
  272.                 case BLKSUM:
  273.                     sprintf(alertstr,fmtstr,wert2=sum(begin, end));
  274.                     nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  275.                       fprintf(fp,"%s",alertstr);
  276.                     sprintf(alertstr,Anumerik[2],wert2);
  277.                     break;
  278.                 case BLKMEAN:
  279.                     n=count(begin, end);
  280.                     if(n>1)
  281.                     {
  282.                         sprintf(alertstr,fmtstr,wert3=(sum(begin, end)/(double)n));
  283.                        nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  284.                         fprintf(fp,"%s",alertstr);
  285.                         sprintf(alertstr,Anumerik[3],wert3);
  286.                     }
  287.                     else
  288.                         form_alert(1,Anumerik[4]);
  289.                     break;
  290.                 case BLKSDEV:
  291.                     wert4=sdev(begin, end);
  292.                     if(wert4>=0)
  293.                     {
  294.                         sprintf(alertstr,fmtstr,wert4);
  295.                        nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  296.                         fprintf(fp,"%s",alertstr);
  297.                         sprintf(alertstr,Anumerik[5],wert4);
  298.                     }
  299.                     else
  300.                          form_alert(1,Anumerik[6]);
  301.                     break;
  302.                 case BLKMWST:
  303.                     wert5=steuer(begin, end);
  304.                     if(wert5>=0)
  305.                     {
  306.                         sprintf(alertstr,fmtstr,wert5);
  307.                        nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  308.                         fprintf(fp,"%s",alertstr);
  309.                         sprintf(alertstr,Anumerik[7],wert5);
  310.                     }
  311.                     else
  312.                          form_alert(1,Anumerik[8]);
  313.                     break;
  314.                 case BLKINTER:
  315.                 extract(&begin->string[begin->begcol], 
  316.                         begin->endcol-begin->begcol,
  317.                         filename);
  318.                     strcchg(filename,',','.'); /* Komma gegen Punkt */
  319.                     wert6=interpretiere(filename, &fehler);
  320.                     if(!fehler)
  321.                     {
  322.                         sprintf(alertstr,fmtstr,wert6);
  323.                        nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  324.                         fprintf(fp,"%s",alertstr);
  325.                         sprintf(alertstr,Anumerik[13],wert6);
  326.                     }
  327.                     else
  328.                     {
  329. /*
  330.                         sprintf(alertstr,Anumerik[15],(int)wert6);
  331.                         form_alert(1,alertstr);
  332. */
  333.                         sprintf(alertstr,Anumerik[15+fehler]);
  334.                         form_alert(1,alertstr);
  335.                         hide_blk(wp, begin, end);
  336.                         graf_mouse(M_OFF,NULL);
  337.                         Wcursor(wp);
  338.                         wp->col = (begin->begcol + (int)wert6) - wp->wfirst/wp->wscroll - 1;
  339.                         wp->cspos = Wshiftpage(wp,0,wp->cstr->used);
  340.                         Wcursor(wp);
  341.                         graf_mouse(M_ON,NULL);
  342.                         *alertstr=0;
  343.                     }
  344.                     break;
  345.                 case BLKALL:
  346.                     n=count(begin,end);
  347.                     if(n>1)
  348.                     {
  349.                         fprintf(fp,"%d\n",wert1=count(begin, end));
  350.  
  351.                         sprintf(alertstr,fmtstr,wert2=sum(begin, end));
  352.                        nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  353.                         fprintf(fp,"%s",alertstr);
  354.     
  355.                         sprintf(alertstr,fmtstr,wert3=(sum(begin, end)/(double)n));
  356.                        nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  357.                         fprintf(fp,"%s",alertstr);
  358.     
  359.                         sprintf(alertstr,fmtstr,wert4=sdev(begin, end));
  360.                        nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  361.                          fprintf(fp,"%s",alertstr);
  362.     
  363.                         sprintf(alertstr,fmtstr,wert5=steuer(begin, end));
  364.                        nconvert(alertstr); /* konvertieren entspr. der Einstellungen */
  365.                         fprintf(fp,"%s",alertstr);
  366.  
  367.                         sprintf(alertstr,Anumerik[9],wert1,wert2,wert3,wert4,wert5);
  368.                     }
  369.                     else
  370.                         form_alert(1,Anumerik[4]);
  371.                     break;
  372.             }
  373.             fclose(fp);
  374.             if(*alertstr)
  375.                 form_alert(1,alertstr);
  376.         }
  377.         else
  378.             form_alert(1,Anumerik[10]);
  379.         graf_mouse(ARROW,NULL);
  380.     }
  381. #endif
  382. }
  383.  
  384. void hndl_nummenu(OBJECT *tree, int start, int mode)
  385. {
  386.     int exit_obj,c,d,e,f,g;
  387.     char a[6],b[2],h[6];
  388.  
  389.     form_read(tree,NUMMWSTN,a);
  390.     form_read(tree,NUMMWSTE,h);
  391.     form_read(tree,NUMKOMMA,b);
  392.     c=tree[NUMNDT].ob_state;
  393.     d=tree[NUMNAMI].ob_state;
  394.     e=tree[NUMTSEP].ob_state;
  395.     f=tree[NUMNORM].ob_state;
  396.     g=tree[NUMERM ].ob_state;
  397.     form_exopen(tree,mode);
  398.     do
  399.     {
  400.         exit_obj=form_exdo(tree,start);
  401.         switch(exit_obj)
  402.         {
  403.             case NUMHELP:
  404.                 if(form_alert(2,Anumerik[11])==2)
  405.                     form_alert(1,Anumerik[14]);
  406.                 objc_change(tree,exit_obj,0,tree->ob_x,tree->ob_y,tree->ob_width,tree->ob_height,tree[exit_obj].ob_state&~SELECTED,TRUE);
  407.                 break;
  408.             default:
  409.                 break;
  410.         }
  411.     }
  412.     while(exit_obj==NUMHELP);
  413.     form_exclose(tree,exit_obj,mode);
  414.     if(exit_obj==NUMABBR)
  415.     {
  416.         form_write(tree,NUMMWSTN,a,FALSE);
  417.         form_write(tree,NUMMWSTE,h,FALSE);
  418.         form_write(tree,NUMKOMMA,b,FALSE);
  419.         tree[NUMNDT].ob_state=c;
  420.         tree[NUMNAMI].ob_state=d;
  421.         tree[NUMTSEP].ob_state=e;
  422.         tree[NUMNORM].ob_state=f;
  423.         tree[NUMERM ].ob_state=g;
  424.     }
  425.     else
  426.     {
  427.         form_read(tree, NUMMWSTN, mwst); /* MWST lesen */
  428.         if(!isfloat(mwst))                  /* korrektes Format? */
  429.         {
  430.             form_alert(1,Anumerik[12]);
  431.             form_write(tree,NUMMWSTN,a,FALSE); /* Nein, zurücksetzen */
  432.         }
  433.         form_read(tree, NUMMWSTE, mwst); /* MWST lesen */
  434.         if(!isfloat(mwst))                  /* korrektes Format? */
  435.         {
  436.             form_alert(1,Anumerik[12]);
  437.             form_write(tree,NUMMWSTE,h,FALSE); /* Nein, zurücksetzen */
  438.         }
  439.         nkst=atoi(form_read(tree,NUMKOMMA,b));/* Nachkommastellen lesen */
  440.        if(tree[NUMNDT].ob_state & SELECTED)
  441.           komma=TRUE;
  442.        else
  443.           komma=FALSE;
  444.     }
  445. }
  446.